/**
 * WebRiders Framework - Utility functions
 * 
 * @version 0.9
 * @author Bryzgunov Rostislav (aka kottenator)
 * @license MIT or GPL
 * 
 * Dependencies:
 *     webriders.core-0.9.js
 */

WebRiders.util = {
    /**
     * Create namespace or return existent.
     *
     * @param {String} name - namespace name. E.g. 'WR.CustomSite'
     *
     * @return {Object} - namespace object. May be not empty
     */
    namespace: function(name) {
        name = name.split('.');
        var c = window, n = '';
        while(n = name.shift()) {
            if (typeof c[n] == 'undefined')
                c[n] = {};
            c = c[n];
        };
        return c;
    },

    /**
     * Alias for the 'namespace' method
     */
    ns: function() { return this.namespace.apply(this, arguments); },

    /**
     * Load script dependencies
     *
     * @param {String/Array} scripts - path:
     *     "my/script.js"
     *     "my/script1.js my/script2.js"
     *     "my/script1.js, my/script2.js  my/script3.js ,    my/script4.js"
     *     ["my/script1.js", "my/script2.js", "my/script3.js"]
     * @param {Object} config
     *
     * @config {Function} callback. Not required
     * @config {*} context - callback context (scope) object. Not required
     * @config {Boolean} cache - true to leave URL unchanged. false to add '?_=12442432' to it. Default: false
     * @config {Boolean} async - true to load scripts asynchronous. Default: false 
     */
    require: function(scripts, config) {
        scripts = scripts || '';
        config = config || {};

        if (typeof scripts == "string")
            scripts = scripts.replace(/^\s+|\s+$/g, '').replace(/\s*,\s*|\s+/g, ',').split(',');

        if (!$.isArray(scripts))
            return false;

        var loaded = this.require.loaded = this.require.loaded || {};

        for (var i = 0, l = scripts.length; i < l; i++) {
            var script = scripts[i] || '';
            if (script.search(/^https?:\/\//) !== 0) {
                var loc = window.location, path = '';
                if (script.indexOf('/') === 0)
                    path = window.location.protocol + '//' + window.location.host;
                else
                    path = (config.path || this.require.defaultPath || '');
                script = path + script;
            }

            if (!loaded[script]) {
                var success = function(data, textStatus) {
                    loaded[script] = true;
                    if (typeof config.callback == "function")
                        config.callback.apply(this, arguments);
                };

                $.ajax({
                    url: script,
                    dataType: 'script',
                    success: success,
                    context: config.context,
                    cache: !!config.cache,
                    async: !!config.async
                });
            }
        }

        return true;
    },

    /**
     * Get shuffled subset from the list
     *
     * @param {Array} list
     * @param {Number} cnt - how many elements should we get? Default: all
     */
    randomSample: function(list, cnt) {
        cnt = cnt || list.length;
        list = $.extend([], list);
        var new_list = [];
        while (cnt) {
            cnt--;
            new_list.push(list.splice(Math.round(Math.random() * (list.length - 1)), 1)[0]);
        }
        return new_list;
    }
}

/**
 * Simple string template
 * @param {String} source
 * @constructor
 */
WR.util.Template = function(source) {
    this.source = source;
}

WR.util.Template.prototype = {
    source: '',

    apply: function(config) {
        config = config || {};
        return this.source.replace(
            /{{\s*(.*?)\s*}}/g,
            function (a, b) {
                var r = config[b];
                if (typeof r == "undefined")
                    r = "";
                return r;
            }
        );
    }
}
